package com.ynu.yx.chatroleai.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ynu.yx.chatroleai.dao.UserDao;
import com.ynu.yx.chatroleai.converter.UserConverter;
import com.ynu.yx.chatroleai.dto.UserDto;
import com.ynu.yx.chatroleai.dto.UserInfoDto;
import com.ynu.yx.chatroleai.dto.UserRegisterDto;
import com.ynu.yx.chatroleai.model.User;
import com.ynu.yx.chatroleai.model.enums.UserRole;
import com.ynu.yx.chatroleai.utils.IdGenerator;
import com.ynu.yx.chatroleai.utils.MsgOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.jws.soap.SOAPBinding;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Objects;


@Service
public class UserService {
    @Resource
    private UserDao userDao;
    @Resource
    private UserConverter userConverter;
    @Resource
    private IdGenerator idGenerator;


    // 根据uid构建QueryWrapper
    public QueryWrapper<User> getQueryWrapperByUid(Long uid) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        if (uid != null) {
            queryWrapper.eq("uid", uid);
        }
        return queryWrapper;
    }

    // 根据uid构建UpdateWrapper
    public UpdateWrapper<User> getUpdateWrapperByUid(Long uid) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        if (uid != null) {
            updateWrapper.eq("uid", uid);
        }
        return updateWrapper;
    }

    // 判断角色是否有效
    public boolean isRoleValid(User user) {
        for (UserRole userRole : UserRole.values()) {
            if (userRole.getValue().equals(user.getRole())) {
                return true;
            }
        }
        return false;
    }

    //----------------------用户信息--------------------------
    //-------------增--------------
    // 注册用户，返回值：-1表示用户名无效，其他值表示插入结果
    public MsgOperation registerUser(UserRegisterDto urdto) {
        if (!urdto.getUsername().matches("^\\w+$") || urdto.getUsername().length()<3 ) { //  ‘\\w’ 等价于 [a-zA-Z0-9_]（字母、数字、下划线）
            return new MsgOperation("-1", "用户名长度小于3或含特殊字符"); // 无效的用户名
        }

        if (userDao.selectOne(new QueryWrapper<User>().eq("username", urdto.getUsername())) != null) {
            return new MsgOperation("-2", "用户名已存在");// 用户名已存在
        }
        if (urdto.getPasswordHash().length() < 6) {
            return new MsgOperation("-3", "密码过短"); // 密码过短
        }
        if (!urdto.getPasswordHash().matches(".*\\d.*") || !urdto.getPasswordHash().matches(".*[a-zA-Z].*")) {
            return new MsgOperation("-4", "密码必须包含字母和数字"); // 密码必须包含字母和数字
        }


        User user = userConverter.reDtoToUser(urdto);

        Long uid = idGenerator.generateUniqueId(userDao, "uid");
        user.setUid(uid); // 生成唯一的uid
        if (user.getUid() == null) {
            return new MsgOperation("-5", "uid生成失败"); // uid生成失败
        }

        boolean isRoleValid = isRoleValid(user);

        if (!isRoleValid) {
            user.setRole(UserRole.USER.getValue()); // 默认角色
        }

        if (user.getRole().equals(UserRole.ADMIN.getValue())) {
            user.setIsRoleReviewed(0); // 管理员角色需要审核
        } else {
            user.setIsRoleReviewed(1); // 其他角色无需审核
        }
        user.setIsDeleted(0); // 0表示未删除，1表示已删除
        userDao.insert(user);
        return new MsgOperation("1", "注册用户成功");
    }

    //-------------删--------------
    // 删除用户(逻辑删除），返回值：删除的记录数
    public MsgOperation deleteUserByUid(Long uid) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("uid", uid).set("is_deleted", 1);
        userDao.update(null, updateWrapper);
        return new MsgOperation("1", "删除用户成功");
    }

    public MsgOperation deleteUserByUsername(String username) {
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("username", username).set("is_deleted", 1);
        userDao.update(null, updateWrapper);
        return new MsgOperation("1", "删除用户成功");
    }

    //-------------查--------------
    // 根据id获取用户
    public UserDto getUserById(Long id) {
        return userConverter.toDto(userDao.selectById(id));
    }

    // 根据Uid获取用户
    public UserDto getUserByUid(Long uid) {
        QueryWrapper<User> queryWrapper = getQueryWrapperByUid(uid);
        return userConverter.toDto(userDao.selectOne(queryWrapper));
    }

    // 根据用户名获取用户
    public UserDto getUserByUsername(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return userConverter.toDto(userDao.selectOne(queryWrapper));
    }

    // 根据用户名和密码登录
    public MsgOperation loginByUsername(String username, String password) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        User user = userDao.selectOne(queryWrapper);
        if (user == null) {
            return new MsgOperation("-1", "用户不存在");
        }
        if (user.getPasswordHash().equals(password)) {
            UpdateWrapper<User> updateWrapper = getUpdateWrapperByUid(user.getUid());
            updateWrapper.set("last_login_at",  LocalDateTime.now());
            userDao.update(null, updateWrapper);

            UserDto ud = userConverter.toDto(user);
            return new MsgOperation("1", "登录成功", ud);
        }
        return new MsgOperation("-2", "用户密码错误");

    }

    //-------------改--------------
    // 更新用户信息，返回值：更新的记录数
    public MsgOperation updateUserNormalInfoByUid(Long uid, UserInfoDto userInfoDto) {
        if (userInfoDto == null || uid == null) {
            return new MsgOperation("-1", "用户信息不完整或缺少Uid");
        }
        // 按 uid 查出原记录
        User user = userDao.selectOne(getQueryWrapperByUid(uid));
        if (user == null) return new MsgOperation("0", "用户不存在");       // 用户不存在

        // 把 userDto 的非空值拷到 user（忽略主键、业务主键）
        BeanUtils.copyProperties(userInfoDto, user, "id", "uid");

        // 按主键更新
        userDao.updateById(user);
        return new MsgOperation("1", "更新用户信息成功");
    }

    // 更新用户名
    public MsgOperation updateUsernameByUid(Long uid, String newUsername) {
        User user = userDao.selectOne(getQueryWrapperByUid(uid));

        if (!newUsername.matches("^\\w+$") || newUsername.length()<3 ) { //  ‘\\w’ 等价于 [a-zA-Z0-9_]（字母、数字、下划线）
            return new MsgOperation("-1", "无效的用户名"); // 无效的用户名
        }

        if (user.getUsername().equals(newUsername)) {
            return new MsgOperation("-2", "未更改用户名");
        }

        if (user.getUpdatedUserNameAt() != null){
            Duration duration = Duration.between(user.getUpdatedUserNameAt(), LocalDateTime.now());
            if (duration.toHours() < 24) {
                return new MsgOperation("-3", "用户名更新过于频繁（距上一次更新不足24小时）"); // 用户名更新过于频繁
            }
        }

        UpdateWrapper<User> updateWrapper = getUpdateWrapperByUid(uid);
        if (userDao.selectOne(new QueryWrapper<User>().eq("username", newUsername)) != null) {
            return new MsgOperation("-4", "用户名已存在"); // 用户名已存在
        }

        updateWrapper.set("username", newUsername).set("updated_user_name_at", LocalDateTime.now());
        userDao.update(null, updateWrapper);
        return new MsgOperation("1", "更新用户名成功");
    }

    // 更新密码
    public MsgOperation updatePwdByUid(Long uid, String pwd) {
        User user = userDao.selectOne(getQueryWrapperByUid(uid));
        if (user == null) {
            return new MsgOperation("0", "用户不存在"); // 用户不存在
        }
        if (pwd.length() < 6) {
            return new MsgOperation("-1", "密码过短"); // 密码过短
        }
        if (!pwd.matches(".*\\d.*") || !pwd.matches(".*[a-zA-Z].*")) {
            return new MsgOperation("-2", "密码必须包含字母和数字"); // 密码必须包含字母和数字
        }
        UpdateWrapper<User> updateWrapper = getUpdateWrapperByUid(uid).set("password_hash", pwd);
        userDao.update(null, updateWrapper);
        return new MsgOperation("1", "更新密码成功");
    }

    // 更新角色
    public MsgOperation updateRoleByUid(Long uid, String role) {
        User user = userDao.selectOne(getQueryWrapperByUid(uid));
        if (user == null) {
            return new MsgOperation("0", "用户不存在"); // 用户不存在
        }
        boolean isRoleValid = isRoleValid(user);
        if (!isRoleValid) {
            return new MsgOperation("-1", "角色无效"); // 角色无效
        }
        if (role.equals("admin")) {
            user.setIsRoleReviewed(0);
            return new MsgOperation("-2", "等待管理员审核"); // 等待管理员审核
        }
        UpdateWrapper<User> updateWrapper = getUpdateWrapperByUid(uid).set("role", role);;
        userDao.update(null, updateWrapper);
        return new MsgOperation("1", "更新角色成功");
    }

}
